package db;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;


/**
 * Description: 对数据进行处理的DAO的基类,使用了泛型；T类型泛指model包下的所有实体类。
 * 
 * @since  2009/2/21
 * @author ashen
 *  
 */
public abstract class BaseDAO{
	
	/**
	 * tableName为需要操作数据库中表的名字
	 */
	private String tableName;
	
	public void setTableName(String tableName){
		this.tableName=tableName;
	}
	
	public String getTableName(){
		return tableName;
	}
	
	/**
	 * the method save of class BaseDAO
	 * 
	 * 该方法根据对象参数的属性添加一条数据库记录
	 * 
	 * @param hashMap 存储需要添加的记录的HashMap对象
	 * @param transaction 数据库操作类Transaction的对象
	 */
	public void save(HashMap hashMap,Transaction transaction){
		StringBuffer names=new StringBuffer();
    	StringBuffer values=new StringBuffer();
        for(Iterator i=hashMap.entrySet().iterator();i.hasNext();){ 
        	Entry entry=(Entry)i.next();
            Object key = entry.getKey();
            Object value =entry.getValue();  
	        names.append(key+",");
			values.append(value+",");
        }
        String sqlStr="insert into " +tableName+"("
        	+names.substring(0,names.length()-1)+")"
        	+" values("+values.substring(0,values.length()-1)+")";
        transaction.excute(sqlStr);
	}
	
	/**
	 * the method save of class BaseDAO
	 * 
	 * 该方法根据对象参数的属性添加一条数据库记录
	 * 自动提交事务
	 * 
	 * @param hashMap 存储需要添加的记录的HashMap对象
	 * @return 返回操作成功与否
	 */
	public boolean save(HashMap hashMap){
		Transaction transaction=new Transaction();
		save(hashMap,transaction);
		return transaction.commit();
	}
	
	/**
	 * the method update of class BaseDAO
	 * 
	 * 该方法更新指定记录的数据
	 * 
	 * @param hashMap 数据库需要更新记录的对应HashMap对象
	 * @param PKName 数据库需要更新记录的表的主键
	 * @param PKValue 数据库需要更新记录的表的主键值
	 * @param transaction 数据库操作类Transaction的对象
	 */
	public<E> void update(HashMap hashMap,String PKName,E PKValue,Transaction transaction){
		String sqlStr="";
		StringBuffer sets=new StringBuffer();
		for(Iterator i=hashMap.entrySet().iterator();i.hasNext();){ 
        	Entry entry=(Entry)i.next();
            Object key = entry.getKey();
            Object value =entry.getValue();   
            if(!key.equals(PKName))
            	sets.append(key+"="+value+",");
		} 
		sqlStr="update " +tableName+" set "+sets.substring(0,sets.length()-1)
			+" where "+PKName+"="+PKValue;		
		transaction.excute(sqlStr);
	}
	
	/**
	 * the method update of class BaseDAO
	 * 
	 * 该方法更新指定记录的数据，主键由两个字段组成
	 * 
	 * @param hashMap 数据库需要更新记录的对应HashMap对象
	 * @param PKName1 数据库需要更新记录的表的主键之一
	 * @param PKValue1 数据库需要更新记录的表的主键值之一
	 * @param PKName2 数据库需要更新记录的表的主键之一
	 * @param PKValue2 数据库需要更新记录的表的主键值之一
	 * @return 返回该操作成功与否
	 */
	public<E> boolean update(HashMap hashMap,String PKName1,E PKValue1,String PKName2,E PKValue2){
		String sqlStr="";
		StringBuffer sets=new StringBuffer();
		for(Iterator i=hashMap.entrySet().iterator();i.hasNext();){ 
        	Entry entry=(Entry)i.next();
            Object key = entry.getKey();
            Object value =entry.getValue();   
            if(!key.equals(PKName1)&&!key.equals(PKName2))
            	sets.append(key+"="+value+",");
		} 
		sqlStr="update " +tableName+" set "+sets.substring(0,sets.length()-1)
			+" where "+PKName1+"="+PKValue1+" and "+PKName2+"="+PKValue2;
		Transaction transaction=new Transaction();
		transaction.excute(sqlStr);
		return transaction.commit();
	}
	
	/**
	 * the method update of class BaseDAO
	 * 
	 * 该方法更新指定记录的数据
	 * 
	 * @param hashMap 数据库需要更新记录的对应HashMap对象
	 * @param PKValue 数据库需要更新记录的表的主键值
	 * @return 返回该操作成功与否
	 */
	public boolean update(HashMap hashMap,String PKName){
		Transaction transaction=new Transaction();
		update(hashMap,PKName,hashMap.get(PKName),transaction);
		return transaction.commit();
		
	}
	
	/**
	 * the method update of class BaseDAO
	 * 
	 * 该方法更新指定记录的数据
	 * 
	 * @param hashMap 数据库需要更新记录的对应HashMap对象
	 * @param PKValue 数据库需要更新记录的表的主键
	 * @param transaction 数据库操作类Transaction的对象
	 */
	public void update(HashMap hashMap,String PKName,Transaction transaction){
		update(hashMap,PKName,hashMap.get(PKName),transaction);
	}
	
	/**
	 * the method deleteBySql of class BaseDAO
	 * 
	 * 该方法按指定SQL语句删除记录
	 * 自动提交事务
	 * 
	 * @param sqlStr SQL语句
	 * @return 返回该操作成功与否
	 */
	public<E> boolean deleteBySql(String sqlStr){  
		Transaction transaction=new Transaction();
        deleteBySql(sqlStr,transaction);
        return transaction.commit();
	}
	
	/**
	 * the method deleteBySql of class BaseDAO
	 * 
	 * 该方法按指定SQL语句删除记录
	 * 
	 * @param sqlStr SQL语句
	 * @param transaction 数据库操作类Transaction的对象
	 */
	public<E> void deleteBySql(String sqlStr,Transaction transaction){  
        transaction.excute(sqlStr);
	}
	
	/**
	 * the method delete of class BaseDAO
	 * 
	 * 该方法删除一个指定字段匹配指定字段值的记录
	 * 自动提交事务
	 * 
	 * @param propertyName 指定字段名
	 * @param propertyValue 指定字段值
	 * @return 返回该操作成功与否
	 */
	public<E> boolean delete(String propertyName,E propertyValue){
		String sqlStr="delete from " +tableName+
				" where "+propertyName+"="+propertyValue;  
		return deleteBySql(sqlStr);
	}
	
	/**
	 * the method delete of class BaseDAO
	 * 
	 * 该方法删除一个指定字段匹配指定字段值的记录
	 * 
	 * @param propertyName 指定字段名
	 * @param propertyValue 指定字段值
	 * @param transaction 数据库操作类Transaction的对象
	 */
	public<E> void delete(String propertyName,E propertyValue,Transaction transaction){
		String sqlStr="delete from " +tableName+
				" where "+propertyName+"="+propertyValue;  
		deleteBySql(sqlStr,transaction);
	}
	
	/**
	 * the method delete of class BaseDAO
	 * 
	 * 该方法删除两个指定字段都匹配指定字段值的记录
	 * 自动提交事务
	 * 
	 * @param propertyName1 指定字段名1
	 * @param propertyValue1 指定字段值1
	 * @param propertyName2 指定字段名2
	 * @param propertyValue2 指定字段值2
	 * @return 返回该操作成功与否
	 */
	public<E> boolean delete(String propertyName1,E propertyValue1,String propertyName2,E propertyValue2){
		String sqlStr="delete from " +tableName+
				" where "+propertyName1+"="+propertyValue1+" and "
				+propertyName2+"="+propertyValue2;  
		return deleteBySql(sqlStr);
	}
	
	/**
	 * the method delete of class BaseDAO
	 * 
	 * 该方法删除两个指定字段都匹配指定字段值的记录
	 * 
	 * @param propertyName1 指定字段名1
	 * @param propertyValue1 指定字段值1
	 * @param propertyName2 指定字段名2
	 * @param propertyValue2 指定字段值2
	 * @param transaction 数据库操作类Transaction的对象
	 */
	public<E> void delete(String propertyName1,E propertyValue1,
			String propertyName2,E propertyValue2,Transaction transaction){
		String sqlStr="delete from " +tableName+
				" where "+propertyName1+"="+propertyValue1+" and "
				+propertyName2+"="+propertyValue2;  
		deleteBySql(sqlStr,transaction);
	}
	
	/**
	 * the method findBySQL of class BaseDAO
	 * 
	 * 该方法通过指定SQL语句查寻记录
	 * 
	 * @param sqlStr SQL查询语句
	 * @param transaction 数据库操作类Transaction的对象
	 * @return 存储查询到的记录的HashMap对象数组
	 */
	public ArrayList<HashMap> findBySQL(String sqlStr,Transaction transaction){			
        return transaction.query(sqlStr);
	}
	
	/**
	 * the method findAllBase of class BaseDAO
	 * 
	 * 该方法返回所有表中的记录
	 * 
	 * @param transaction 数据库操作类Transaction的对象
	 * @return HashMap类型对象记录集
	 */
	public ArrayList<HashMap> findAllBase(Transaction transaction){	        		
		String sqlStr="select * from " +getTableName();
		return findBySQL(sqlStr,transaction);
	}
	
	/**
	 * the method findByProperty of class BaseDAO
	 * 
	 * 该方法通过字段名查找匹配记录,
	 * 
	 * @param propertyName 字段名
	 * @param propertyValue E类型的字段值
	 * @param transaction 数据库操作类Transaction的对象
	 * @return HashMap类型对象记录集
	 */
	public<E> ArrayList<HashMap> findByProperty(String propertyName,
			E propertyValue,Transaction transaction){
		String sqlStr="select distinct * from " +getTableName()+" where "
			+propertyName+"="+propertyValue;
		return findBySQL(sqlStr,transaction);
	}
	
	/**
	 * the method findByPK of class BaseDAO
	 * 
	 * 该方法通过指定主键值查找对象,主键由一个字段组成
	 * 
	 * @param PKName 主键名
	 * @param PKValue 主键值
	 * @param transaction 数据库操作类Transaction的对象
	 * @return 查询到的HashMap类型对象
	 */
	public<E> HashMap findByPK(String PKName,E PKValue,Transaction transaction){	        
		String sqlStr="select distinct * from " +getTableName()+
				" where "+PKName+"="+PKValue;
		HashMap result= transaction.queryOneResult(sqlStr);    	        
		return result;
	}
	
	/**
	 * the method findByPK of class BaseDAO
	 * 
	 * 该方法通过指定主键值查找对象，主键由两个字段组成
	 * 
	 * @param PKName1 主键名1
	 * @param PKValue1 主键值1
	 * @param PKName2 主键名2
	 * @param PKValue2 主键值2
	 * @param transaction 数据库操作类Transaction的对象
	 * @return 查询到的HashMap类型对象
	 */
	public<E,F> HashMap findByPK(String PKName1,E PKValue1,
			String PKName2,F PKValue2,Transaction transaction){	        
		String sqlStr="select * from " +getTableName()+
				" where "+PKName1+"="+PKValue1+" and "
				+PKName2+"="+PKValue2;
		HashMap result= transaction.queryOneResult(sqlStr);    	        
		return result;
	}
	
	/**
	 * the method findByKeyword of class BaseDAO
	 * 
	 * 该方法通过指定两个字段的关键字查找T类型对象
	 * 
	 * @param keywordName 字段名
	 * @param keywordValue 关键字
	 * @param transaction 数据库操作类Transaction的对象
	 * @return 查询到的HashMap类型对象列表
	 */
	public ArrayList<HashMap> findLikeKeyword(String keywordName,
			String keywordValue,Transaction transaction){	        		
		String sqlStr="select distinct * from " +getTableName()+
				" where "+keywordName+" like '%"+keywordValue+"%'";  	        
        return findBySQL(sqlStr,transaction);
	}
	
	/**
	 * the method findByKeyword of class BaseDAO
	 * 
	 * 该方法通过指定两个字段的关键字查找T类型对象
	 * 
	 * @param keywordName1 字段名1
	 * @param keywordValue1 关键字1
	 * @param keywordName2 字段名2
	 * @param keywordValue2 关键字2
	 * @param type 资源类型
	 * @param transaction 数据库操作类Transaction的对象
	 * @return 查询到的HashMap类型对象列表
	 */
	public ArrayList<HashMap> findLikeKeyword(String keywordName1,String keywordValue1,
			String keywordName2,String keywordValue2,String type,Transaction transaction){	        		
		String sqlStr="select distinct * from " +getTableName()+
				" where type='"+type+"' and ("+keywordName1+" like '%"+keywordValue1
			+"%' or "+keywordName2+" like '%"+keywordValue2+"%')";  	        
        return findBySQL(sqlStr,transaction);
	}
	
	/**
	 * the method getFormatString of class BaseDAO
	 * 
	 * 若要存储的参数字符串的对应字段类型为Date,Time,Timestamp,String,
	 * 可以使用该方法生成SQL语句需要的字段值
	 * 
	 * @param str 需要格式化的字符串
	 * @return 格式化后的字符串
	 */
	public<E> String getFormatString(E str){
		return "'"+str.toString().trim()+"'";
	}

	
}
